package com.hucheng.activity.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hucheng.activity.entity.ExchangeDO;
import com.hucheng.activity.entity.ExchangeDetailsDO;
import com.hucheng.activity.mapper.ExchangeDetailsMapper;
import com.hucheng.activity.mapper.ExchangeMapper;
import com.hucheng.activity.mapper.UserPointMapper;
import com.hucheng.activity.query.ExchangeDetailsQuery;
import com.hucheng.activity.query.ExchangeQuery;
import com.hucheng.activity.service.ExchangeService;
import com.hucheng.activity.service.UserPointActivityService;
import com.hucheng.activity.vo.ExchangePrizeVO;
import com.hucheng.activity.vo.ExchangeVO;
import com.hucheng.activity.vo.UserPointVO;
import com.hucheng.common.constant.RedisConstant;
import com.hucheng.common.exception.EduException;
import com.hucheng.common.page.CommonPager;
import com.hucheng.common.page.PageParameter;
import com.hucheng.common.utils.RedisUtils;
import com.hucheng.common.utils.ValidatorUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 凉白开不加冰
 * @Version: 0.0.1V
 * @Date: 2019-07-15
 * @Description: 兑换活动实现类
 **/
@Component
@Service(interfaceClass = ExchangeService.class, retries = -1, timeout = 5000)
public class ExchangeServiceImpl implements ExchangeService {

    @Autowired
    private ExchangeMapper exchangeMapper;

    @Autowired
    private ExchangeDetailsMapper exchangeDetailsMapper;

    @Autowired
    private UserPointMapper userPointMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserPointActivityService userPointActivityService;

    @Override
    public CommonPager<ExchangeVO> list(ExchangeQuery exchangeQuery) {
        return new CommonPager<>(new PageParameter(
                exchangeQuery.getPageParameter().getCurrentPage(),
                exchangeQuery.getPageParameter().getPageSize(),
                exchangeMapper.count(exchangeQuery)),
                exchangeMapper.list(exchangeQuery).stream().map(ExchangeVO::buildExchangeVO).collect(Collectors.toList()));
    }

    @Override
    public ExchangePrizeVO exchange(Integer userId, Integer exchangeConfigId, Integer exchangeNo) throws EduException {
        //获取活动配置
        String exchangeInfo = RedisUtils.getString(stringRedisTemplate, RedisConstant.EXCHANGE_PRIZE_KEY + exchangeConfigId);
        if (exchangeInfo == null || ValidatorUtils.isEmpty(exchangeInfo)) {
            //去数据库拿去活动配置
            ExchangeQuery exchangeQuery = new ExchangeQuery();
            exchangeQuery.setStatus(1);
            exchangeQuery.setExchangeConfigId(exchangeConfigId);
            ExchangeDO exchangeDO = exchangeMapper.get(exchangeQuery);
            ExchangeVO exchangeVO = ExchangeVO.buildExchangeVO(exchangeDO);
            exchangeInfo = JSONObject.toJSONString(exchangeVO);
            if (exchangeVO != null) {
                RedisUtils.set(stringRedisTemplate, RedisConstant.EXCHANGE_PRIZE_KEY + exchangeVO.getExchangeConfigId(), JSONObject.toJSONString(exchangeVO));
            }
        }
        //判断活动是否开始及结束
        JSONObject exchangeJson = JSONObject.parseObject(exchangeInfo);
        if (exchangeJson == null) {
            throw new EduException(160000);
        }
        checkLuckPrizeStatus(exchangeJson.getDate("dateStart"), exchangeJson.getDate("dateEnd"));
        //获取用户兑换次数
        ExchangeDetailsQuery exchangeDetailsQuery = new ExchangeDetailsQuery();
        exchangeDetailsQuery.setUserId(userId);
        exchangeDetailsQuery.setExchangeNo(exchangeNo);
        exchangeDetailsQuery.setExchangeConfigId(exchangeConfigId);
        int count = exchangeDetailsMapper.count(exchangeDetailsQuery);
        //奖品兑换限制
        JSONObject exchangeRemark = exchangeJson.getJSONObject("exchangeRemark");
        JSONArray exchangeList = exchangeRemark.getJSONArray("exchange_list");
        List<ExchangePrizeVO> list = exchangeList.toJavaList(ExchangePrizeVO.class);
        ExchangePrizeVO exchangePrizeVO = null;
        for (ExchangePrizeVO e : list) {
            if (e.getExchangeNo().equals(exchangeNo)) {
                exchangePrizeVO = e;
                break;
            }
        }
        if (exchangePrizeVO == null) {
            throw new EduException(160003);
        }

        int point = exchangePrizeVO.getExchangePoint();
        //用户是否存在免费、活动是否有免费抽奖次数
        UserPointVO userPointVO = UserPointVO.buildUserPointVO(userPointMapper.get(userId));
        //判断用户积分是否足够
        if (userPointVO == null) {
            throw new EduException(150000);
        }
        if (userPointVO.getPoint() < point) {
            throw new EduException(150000);
        }
        if (exchangePrizeVO.getExchangeLimit() > 0) {
            if (exchangePrizeVO.getExchangeLimit() == count) {
                throw new EduException(160002);
            }
        }
        userPointActivityService.subtractPoint(point, exchangePrizeVO.getExchangeName(), userId);
        //新增兑换记录
        ExchangeDetailsDO exchangeDetailsDO = new ExchangeDetailsDO();
        exchangeDetailsDO.setUserId(userId);
        exchangeDetailsDO.setExchangeConfigId(exchangeConfigId);
        exchangeDetailsDO.setExchangeNo(exchangePrizeVO.getExchangeNo());
        exchangeDetailsDO.setExchangeName(exchangePrizeVO.getExchangeName());
        exchangeDetailsDO.setIsDel(0);
        exchangeDetailsMapper.insert(exchangeDetailsDO);
        return exchangePrizeVO;
    }

    @Override
    public void initExchangeList(ExchangeQuery exchangeQuery) {
        List<ExchangeVO> list = exchangeMapper.list(exchangeQuery).stream().map(ExchangeVO::buildExchangeVO).collect(Collectors.toList());
        list.forEach(exchangeVO -> {
            RedisUtils.set(stringRedisTemplate, RedisConstant.EXCHANGE_PRIZE_KEY + exchangeVO.getExchangeConfigId(), JSONObject.toJSONString(exchangeVO));
        });
    }

    private void checkLuckPrizeStatus(Date start, Date end) throws EduException {
        Date date = new Date();
        if (date.getTime() < start.getTime()) {
            //秒杀未开始
            throw new EduException(160000);
        } else if (date.getTime() > end.getTime()) {
            //秒杀结束
            throw new EduException(160001);
        }
    }


}
